Ya aprendimos a importar datos.
Ahora vamos a ver distintos elementos que necesitamos para procesarlos.
Un algoritmo es un conjunto finito de instrucciones que, si se siguen rigurosamente, llevan a cabo una tarea específica.
Todos los algoritmos se componen de “partes” básicas que se utilizan para crear “partes” más complejas.
El tratamiento, análisis y modelado de datos lo haremos mediante algoritmos.
## [1] TRUE
## [1] "logical"
## [1] TRUE
## [1] 3.141593
## [1] 0
## [1] "numeric"
## [1] TRUE
## [1] "hola mundo"
## [1] "character"
## [1] TRUE
## [1] "1969-07-21"
## [1] "character"
## [1] "Date"
## [1] NA
## [1] "logical"
## [1] TRUE
## [1] FALSE
## [1] FALSE
## [1] TRUE
## [1] "logical"
## [1] "TRUE"
## [1] "character"
## [1] 1
## [1] "numeric"
## [1] "1"
## [1] "character"
| Desde | Hacia |
|---|---|
| logical | numeric |
| logical | character |
| numeric | character |
| numeric | Date |
| character | Date |
## [1] 4
## [1] 3
## [1] 12
## [1] 1.25
## [1] 1
## [1] 27
## [1] 27
## [1] 2.302585
## [1] 4
## [1] TRUE
## [1] FALSE
## [1] TRUE
## [1] FALSE
## [1] TRUE
## [1] TRUE
## [1] FALSE
## [1] 28.2735
## [1] 28.27
Son vectores numéricos enmascarados como caracteres. Se usan para crear grupos usando clasificaciones o codificaciones de las variables de interés. Estos factores pueden o no tener un orden.
Ejemplos: estrato socioeconómico, nivel de estudios, mes, sexo, localidad.
## [1] 1 2 3 4 5
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
## [20] "t" "u" "v" "w" "x" "y" "z"
## [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
## [20] "T" "U" "V" "W" "X" "Y" "Z"
## [1] 1 3 2 15 4 0 0 0 1
## [1] 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
## [20] 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
## [39] 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
## [58] 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
## [77] 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
## [1] 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
## [1] 10.00000 22.85714 35.71429 48.57143 61.42857 74.28571 87.14286
## [8] 100.00000
## [1] a b c d e f g h i j k l m n o p q r s t u v w x y z
## Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z
## [1] 2 3 4 1 3 6 5 2 3 4 1 2 3 4 6
## [1] 2 3 4 1 3 6 5 2 3 4 1 2 3 4 6
## Levels: 1 2 3 4 5 6
## [1] 2 3 4 1 3 6 5 2 3 4 1 2 3 4 6
## Levels: 1 2 3 4 5 6
vector_logico <- c(TRUE,FALSE,FALSE,TRUE,FALSE)
vector_cualquiera <- seq(1, 100, by = 3)
un_vector <- c(1, 2, 3, 4, 5)
otro_vector <- c(6, 7, 8, 9, 10)## [1] 1 4
## [1] 34
## [1] 1 2 3 4 5 6 7 8 9 10
## [1] FALSE TRUE TRUE TRUE TRUE
## [1] FALSE FALSE TRUE TRUE TRUE
## [,1] [,2] [,3]
## [1,] 3 4 5
## [2,] 6 8 10
## [3,] 9 12 15
## [,1] [,2] [,3]
## [1,] FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE
## [1] 1 2 3 4 5
## [1] 3
## [1] 1 2
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
## [,1] [,2]
## [1,] 1 7
## [2,] 2 8
## [3,] 3 9
## [4,] 4 10
## [5,] 5 11
## [6,] 6 12
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 3 5 7 9 11
## [2,] 2 4 6 8 10 12
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 2 6 10
## [3,] 3 7 11
## [4,] 4 8 12
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
## [4,] 10 11 12
## [,1] [,2]
## [1,] 0 6
## [2,] 3 9
## [,1] [,2]
## [1,] 0 3
## [2,] 6 9
## [1] 0 9
## [1] -18
solve(mi_matriz) # Matriz inversa, sólo se puede con matrices cuadradas de determinante distinto de cero## [,1] [,2]
## [1,] -0.5000000 0.3333333
## [2,] 0.1666667 0.0000000
## [1] 2 2
Bibliografía complementaria: Parte 1 Capítulo 2: Linear Algebra, del libro Deep Learning del MIT
cuales_extraer <- c(1, 8, 6, 3) # Creo un vactor con las posiciones que deseo extraer
letters[cuales_extraer] # Extrae las letras 1, 8, 6, 3 del vector letters## [1] "a" "h" "f" "c"
## [1] 4 6 8 10
## [1] 1
## [1] 6
## [1] 0 3
## [1] 3 9
## # A tibble: 53,940 × 1
## x
## <dbl>
## 1 3.95
## 2 3.89
## 3 4.05
## 4 4.2
## 5 4.34
## 6 3.94
## 7 3.95
## 8 4.07
## 9 3.87
## 10 4
## # ℹ 53,930 more rows
## # A tibble: 53,940 × 1
## x
## <dbl>
## 1 3.95
## 2 3.89
## 3 4.05
## 4 4.2
## 5 4.34
## 6 3.94
## 7 3.95
## 8 4.07
## 9 3.87
## 10 4
## # ℹ 53,930 more rows
cuales_extraer = c("x","y","z") # Creo un vector de variables a extraer
diamonds[cuales_extraer] #Hago la extracción## # A tibble: 53,940 × 3
## x y z
## <dbl> <dbl> <dbl>
## 1 3.95 3.98 2.43
## 2 3.89 3.84 2.31
## 3 4.05 4.07 2.31
## 4 4.2 4.23 2.63
## 5 4.34 4.35 2.75
## 6 3.94 3.96 2.48
## 7 3.95 3.98 2.47
## 8 4.07 4.11 2.53
## 9 3.87 3.78 2.49
## 10 4 4.05 2.39
## # ℹ 53,930 more rows
A partir de la base de datos evaluacion, hagamos una prueba de hipótesis para testear si el puntaje obtenido en ciencias (variable ciencias) está influenciado/afectado por el sexo (variable sexo).
Nota: cuando una variable toma dos valores se puede recodificar como una variable dummy.
# Cargo los datos de evaluacion y lo guardo en un objeto llamado evaluacion_xlsx
read_xlsx(
path = "data/evaluacion.xlsx",
sheet= "datos"
) -> evaluacion_xlsx
# Hago la prueba t
t.test(ciencias ~ sexo, data = evaluacion_xlsx) -> t_test_ciencias_sexo
# Llamo los resultados de la prueba t
t_test_ciencias_sexo##
## Welch Two Sample t-test
##
## data: ciencias by sexo
## t = -0.81103, df = 37.626, p-value = 0.4224
## alternative hypothesis: true difference in means between group Femenino and group Masculino is not equal to 0
## 95 percent confidence interval:
## -1.1161022 0.4777622
## sample estimates:
## mean in group Femenino mean in group Masculino
## 9.771739 10.090909
¿Qué podríamos extraer de este objeto?
## List of 10
## $ statistic : Named num -0.811
## ..- attr(*, "names")= chr "t"
## $ parameter : Named num 37.6
## ..- attr(*, "names")= chr "df"
## $ p.value : num 0.422
## $ conf.int : num [1:2] -1.116 0.478
## ..- attr(*, "conf.level")= num 0.95
## $ estimate : Named num [1:2] 9.77 10.09
## ..- attr(*, "names")= chr [1:2] "mean in group Femenino" "mean in group Masculino"
## $ null.value : Named num 0
## ..- attr(*, "names")= chr "difference in means between group Femenino and group Masculino"
## $ stderr : num 0.394
## $ alternative: chr "two.sided"
## $ method : chr "Welch Two Sample t-test"
## $ data.name : chr "ciencias by sexo"
## - attr(*, "class")= chr "htest"
Extraigamos el p-valor de la prueba.
## $p.value
## [1] 0.4224486
## [1] 0.4224486
## [1] 0.4224486
Podemos extraer partes de todos los objetos que tengamos en nuestro ambiente de trabajo.
Ajustemos un modelo de regresión lineal simple usando como variable respuesta el puntaje obtenido en humanidades (variable humanidades) en función del puntaje obtenido en ciencias (variable ciencias).
lm(humanidades ~ ciencias, data = evaluacion_xlsx) -> modelo_humanidades_ciencias
modelo_humanidades_ciencias##
## Call:
## lm(formula = humanidades ~ ciencias, data = evaluacion_xlsx)
##
## Coefficients:
## (Intercept) ciencias
## 1.3645 0.8656
##
## Call:
## lm(formula = humanidades ~ ciencias, data = evaluacion_xlsx)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.0606 -1.1006 -0.0048 0.6411 3.1759
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.3645 1.4660 0.931 0.357
## ciencias 0.8656 0.1464 5.911 4.92e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.267 on 43 degrees of freedom
## Multiple R-squared: 0.4483, Adjusted R-squared: 0.4355
## F-statistic: 34.94 on 1 and 43 DF, p-value: 4.92e-07
¿Qué podríamos extraer de este objeto?
## List of 11
## $ call : language lm(formula = humanidades ~ ciencias, data = evaluacion_xlsx)
## $ terms :Classes 'terms', 'formula' language humanidades ~ ciencias
## .. ..- attr(*, "variables")= language list(humanidades, ciencias)
## .. ..- attr(*, "factors")= int [1:2, 1] 0 1
## .. .. ..- attr(*, "dimnames")=List of 2
## .. .. .. ..$ : chr [1:2] "humanidades" "ciencias"
## .. .. .. ..$ : chr "ciencias"
## .. ..- attr(*, "term.labels")= chr "ciencias"
## .. ..- attr(*, "order")= int 1
## .. ..- attr(*, "intercept")= int 1
## .. ..- attr(*, "response")= int 1
## .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
## .. ..- attr(*, "predvars")= language list(humanidades, ciencias)
## .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric"
## .. .. ..- attr(*, "names")= chr [1:2] "humanidades" "ciencias"
## $ residuals : Named num [1:45] 1.446 1.396 -1.266 0.787 0.103 ...
## ..- attr(*, "names")= chr [1:45] "1" "2" "3" "4" ...
## $ coefficients : num [1:2, 1:4] 1.364 0.866 1.466 0.146 0.931 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:2] "(Intercept)" "ciencias"
## .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
## $ aliased : Named logi [1:2] FALSE FALSE
## ..- attr(*, "names")= chr [1:2] "(Intercept)" "ciencias"
## $ sigma : num 1.27
## $ df : int [1:3] 2 43 2
## $ r.squared : num 0.448
## $ adj.r.squared: num 0.435
## $ fstatistic : Named num [1:3] 34.9 1 43
## ..- attr(*, "names")= chr [1:3] "value" "numdf" "dendf"
## $ cov.unscaled : num [1:2, 1:2] 1.3382 -0.1326 -0.1326 0.0134
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:2] "(Intercept)" "ciencias"
## .. ..$ : chr [1:2] "(Intercept)" "ciencias"
## - attr(*, "class")= chr "summary.lm"
Extraigamos el \(R^2\) ajustado del modelo.
## [1] 0.4354905
El control flow es un conjunto de funciones que permiten manejar las órdenes de manera estructurada y lógica. Las más importantes son:
Todos los lenguajes modernos de programación ofrecen una o más maneras de realizar operaciones iterativas. El poder repetir la misma acción una cantidad indefinida de veces es una de las grandes ventajas de realizar las tareas mediante programación.
## for
Sirve para crear tareas repetitivas de un número de pasos específico.
Uno de los usos más frecuentes de un ciclo for es la configuración de métodos de remuestreo (bootstraping).
#vamos a guardar en una lista los coeficientes de una regresión
coeficientes <- list()
# inicializo el ciclo for
for(i in 1:1000){
#en cada paso
# 1. saco una muestra de 30 estudiantes
muestra <- sample_n(evaluacion_xlsx, 30)
# 2. ajusto un modelo de regresión lineal
lm(humanidades ~ ciencias, data = muestra) -> modelo
# 3. extraigo y almaceno los coeficientes del modelo
coeficientes[[i]] <- coefficients(modelo)
}
# grafico el comportamiento de los coeficientes
coeficientes %>%
transpose %>%
lapply(unlist) %>%
as_tibble() %>%
gather(key = coeficiente, value = valor) %>%
ggplot +
aes(x = valor) +
geom_density() +
facet_wrap(~coeficiente, nrow = 2, scales = "free")Sirve para crear tareas repetitivas que no sabemos después de cuántos pasos terminan. Requiere una inicialización cuidadosa.
Ejemplo: ¿Cuántos sobres tengo que comprar para llenar un álbum de 100 cromos?
# inicializo las condiciones de partida
album <- iteracion <- 0
# creo la condición lógica que permite ejecutar el proceso
aun_falta <- TRUE
# siempre que aun_falta siga siendo verdadero
while(aun_falta){
# en cada ciclo
# 1. actualizo en qué iteración voy
iteracion <- iteracion + 1
# 2. extraigo una muestra de 6 números ("compro un sobre con 6 cromos")
sobre <- sample(100, 6)
# 3.1 tomo el álbum
# 3.2 le combino los cromos que obtuve
# 3.3 ordeno los cromos de menor a mayor
# 3.4 dejo valores únicos (quito cromos duplicados)
# 3.5 actualizo el álbum
album %>% c(sobre) %>% sort %>% unique -> album
# 4. si tengo menos de 100 cromos es porque me falta
length(album) < 100 -> aun_falta
}
# muestro el número de iteraciones
# es decir, cuántos sobres tuve que comprar
iteracion## [1] 59
La estructura if sirve para ejecutar varias rutinas distintas dependiendo de una condición lógica. En caso de que sea necesario, es posible aplicar una rutina alterna con la estructura else.
Ejemplo: Prueba de normalidad.
Diversas pruebas y modelos estadísticos requieren verificar el supuesto de normalidad en los datos.
# cargo la base de datos del PGN y la almaceno en un objeto llamado pgn
read_xlsx(
path = "data/Base de datos PGN 2024.xlsx",
sheet= "Data"
) -> pgn
# extraigo la variable Funcionamiento
# le hago un test de shapiro
# guardo los resultados de la prueba en un objeto llamado prueba_sw
pgn[["Funcionamiento"]] %>% shapiro.test() -> prueba_sw
# estructura condicional
if(prueba_sw$p.value > 0.05){
# Si acepto la hipótesis de normalidad en la variable mpg
# Hago una prueba t
print("La variable Funcionamiento sigue una distribución normal")
print("Realizo una prueba t")
t.test(mpg ~ vs, data = mtcars)
} else {
# Si rechazo la hipótesis de normalidad en la variable mpg
# Hago una prueba Mann-Whitney-Wilcoxon
print("La variable Funcionamiento no sigue una distribución normal")
print("Realizo una prueba Mann-Whitney-Wilcoxon")
wilcox.test(mpg ~ vs, data = mtcars)
}## [1] "La variable Funcionamiento no sigue una distribución normal"
## [1] "Realizo una prueba Mann-Whitney-Wilcoxon"
## Warning in wilcox.test.default(x = DATA[[1L]], y = DATA[[2L]], ...): cannot
## compute exact p-value with ties
##
## Wilcoxon rank sum test with continuity correction
##
## data: mpg by vs
## W = 22.5, p-value = 9.034e-05
## alternative hypothesis: true location shift is not equal to 0